package com.ibm.cps.processors;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.ibm.cps.sql.expression.function.meta.FunctionMetaCreator;
import com.ibm.datamodel.timeseries.TimeSeriesSchema;
import com.ibm.interfaces.ITimeSeriesSchema;
import com.ibm.util.JSONUtility;
import com.ibm.util.exception.CPSException;

public class ProcessorTestBuilder {
	
	private ArrayNode node;
	private String tenantid;
	private String schemaId;
	private String processorId;
	private String source;
	private long version;
	private Map<String,String> attributes = new HashMap<>();
	private ITimeSeriesSchema parentschema;
	
	public ProcessorTestBuilder(String SchemaNodeStr) throws CPSException{
		this(JSONUtility.getArrayFromString(SchemaNodeStr));
	}
	
	public ProcessorTestBuilder(ArrayNode SchemaNode) {
		this(SchemaNode,"tenantid","schemaid",1L,"processorId","source");
	}
	
	public ProcessorTestBuilder(ArrayNode node,String tenantid,String schemaId,long version,String processorId,String source){
		this.node = node;
		this.tenantid = tenantid;
		this.schemaId = schemaId;
		this.version = version;
		this.processorId = processorId;
		this.source = source;
	}


	private ITimeSeriesSchema constructSchema() throws CPSException{
		return new TimeSeriesSchema(tenantid, schemaId, node, version);
	}
	
	public ProcessorTestBuilder addAttribute(String field,String name){
		attributes.put(field, name);
		return this;
	}
	
	public AbstractProcessor build(Class<? extends AbstractProcessor> type) throws CPSException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		parentschema = constructSchema();
		Class<?>[] argTypes = new Class<?>[]{String.class,String.class,String.class,ITimeSeriesSchema.class};
		Object[] args = new Object[]{tenantid,processorId,source,parentschema};
		Constructor<? extends AbstractProcessor> constructor = type.getConstructor(argTypes);
		AbstractProcessor processor = constructor.newInstance(args);
		FunctionMetaCreator creator = new FunctionMetaCreator(type);
		creator.assignProcessorAttributes(processor, attributes);
		processor.open();
		return processor;
	}
	
	public ITimeSeriesSchema getInputSchema(){
		return parentschema;
	}
	

	
	
	public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, CPSException {
//		String inputNode = "[{\"name\":\"phase\",\"datatype\":\"int[]\"}]";
//		ProcessorBuilder builder = new ProcessorBuilder(inputNode).addAttribute("inputField", "phase").addAttribute("outputfield", "output");
//		AbstractProcessor dft = builder.build(DFTProcessor.class);
		
		double[] array = new double[]{1,2,3};
		double[] array1 = new double[]{1,2,3};
		System.out.println(array.getClass().getName());
		System.out.println(Arrays.equals(array, array1));
		Double[] array_1 = new Double[]{1.0,2.0,3.0};
		System.out.println(array_1.getClass().getName());
		
		int[] array_int = new int[]{1,2,3};
		System.out.println(array_int.getClass().getName());
		Integer[] array_Int = new Integer[]{1,2,3};
		System.out.println(array_Int.getClass().getName());

		String[] array_str = new String[]{"a","b"};
		System.out.println(array_str.getClass().getName());
		
		
		
	}
	
}
